import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { message } from 'ant-design-vue';
import dayjs from 'dayjs';
import { v4 as uuidv4 } from '@/utils/guid';

// 创建 axios 实例
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_URL || 'http://localhost/router',
  timeout: 30000,
  headers: {
    'Content-Type': 'application/json',
  },
});

/**
 * 请求拦截器
 */
service.interceptors.request.use(
  (config) => {
    // 获取 token 和其他配置
    const token = localStorage.getItem('token') || '';
    const appkey = import.meta.env.VITE_APP_KEY || '';
    const tnid = import.meta.env.VITE_TENANT_ID || '';
    const from = import.meta.env.VITE_REQUEST_FROM || 'web';
    const version = '1.0.0';
    const client = localStorage.getItem('deviceId') || 'web-client';
    const timestamp = dayjs().format('YYYY-MM-DD HH:mm:ss');

    // 构建标准请求结构
    const requestData = config.data || {};
    
    // 如果 data 中已经有 context 和 request，说明是手动构建的完整请求
    if (!requestData.context && !requestData.request) {
      // 否则按照标准格式封装
      config.data = {
        context: {
          token,
          appkey,
          tnid,
          from,
          version,
          client,
          timestamp,
        },
        request: Array.isArray(requestData) ? requestData : [requestData],
      };
    } else {
      // 补充 context 信息
      config.data = {
        context: {
          token,
          appkey,
          tnid,
          from,
          version,
          client,
          timestamp,
          ...requestData.context,
        },
        request: requestData.request,
      };
    }

    return config;
  },
  (error) => {
    console.error('请求错误:', error);
    return Promise.reject(error);
  }
);

/**
 * 响应拦截器
 */
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const res = response.data;

    // 检查响应状态码
    if (res.code !== undefined && res.code !== '0' && res.code !== 0) {
      // code 不为 0 说明是错误响应
      const errorMsg = res.msg || '请求失败';
      
      // Token 失效，跳转登录
      if (res.code === '401' || res.code === 401 || res.code === '10401') {
        message.error('登录已过期，请重新登录');
        localStorage.removeItem('token');
        localStorage.removeItem('userInfo');
        window.location.href = '/login';
        return Promise.reject(new Error(errorMsg));
      }

      // 其他错误
      message.error(errorMsg);
      return Promise.reject(new Error(errorMsg));
    }

    // 成功响应：code 为 0 或 '0'，返回 data 字段
    return res.data || res;
  },
  (error) => {
    console.error('响应错误:', error);
    
    if (error.response) {
      const status = error.response.status;
      switch (status) {
        case 401:
          message.error('未授权，请重新登录');
          localStorage.removeItem('token');
          window.location.href = '/login';
          break;
        case 403:
          message.error('拒绝访问');
          break;
        case 404:
          message.error('请求地址不存在');
          break;
        case 500:
          message.error('服务器错误');
          break;
        default:
          message.error(`请求失败: ${error.message}`);
      }
    } else if (error.message.includes('timeout')) {
      message.error('请求超时，请稍后重试');
    } else if (error.message.includes('Network Error')) {
      message.error('网络连接失败');
    } else {
      message.error(error.message || '未知错误');
    }

    return Promise.reject(error);
  }
);

/**
 * 封装请求方法
 */
export interface RequestOptions {
  metaid: string;
  table?: string;
  caption?: string;
  kind: 'execute' | 'query' | 'edit';
  data?: any;
  edit?: any[];
  execute?: any[];
  query?: any;
}

/**
 * 通用请求方法
 * @param options 请求选项或选项数组
 */
export function request<T = any>(options: RequestOptions | RequestOptions[]): Promise<T> {
  const requests = Array.isArray(options) ? options : [options];
  
  const requestData = requests.map(item => {
    const req: any = {
      metaid: item.metaid,
      caption: item.caption || '',
      kind: item.kind,
    };

    // 如果有 table 字段，添加到请求中
    if (item.table) {
      req.table = item.table;
    }

    // 如果有 edit、execute、query 字段，按原格式添加
    if (item.edit !== undefined) {
      req.edit = item.edit;
    }
    if (item.execute !== undefined) {
      req.execute = item.execute;
    }
    if (item.query !== undefined) {
      req.query = item.query;
    } else if (item.data !== undefined) {
      // 兼容旧格式：如果没有 query 但有 data，按 query 格式包装
      req.query = { data: item.data };
    }

    return req;
  });

  return service.post('', {
    request: requestData,
  });
}

/**
 * GET 请求（实际还是 POST，但语义上是查询）
 */
export function get<T = any>(metaid: string, data?: any, caption?: string): Promise<T> {
  return request<T>({
    metaid,
    caption: caption || '查询',
    kind: 'query',
    data,
  });
}

/**
 * POST 请求（实际还是 POST，但语义上是执行）
 */
export function post<T = any>(metaid: string, data?: any, caption?: string): Promise<T> {
  return request<T>({
    metaid,
    caption: caption || '执行',
    kind: 'execute',
    data,
  });
}

export default service;
